﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Tecnosop.Dominio;
using Tecnosop.WebUI.Models;
using System.Web.UI;
using Tecnosop.WebUI.Infrastructure.Notification;
using Rotativa;

namespace Tecnosop.WebUI.Controllers
{
    [Authorize]
    public partial class CotizacionesController : Controller
    {
        private Entidades db = new Entidades();

        public virtual ViewResult Index()
        {
            return View(new Cotizaciones
            {
                CotizacionesConvenio = db.COTIZACION_CONVENIO.ToList(),
                CotizacionesVentaDirecta = db.COTIZACION_VENTA_DIRECTA.ToList()
            });
        }

        #region "CRUD Cotizaciones de convenio"

        public virtual ViewResult Details(int id)
        {
            ViewData["TiposEquipo"] = db.TIPO_EQUIPO.ToList();
            //ViewBag.TiposEquipo = 
            COTIZACION_CONVENIO cotizacion_convenio = db.COTIZACION_CONVENIO.Find(id);
            return View(cotizacion_convenio);
        }

        public virtual ActionResult printPdfCotizacion(int id)
        {
            //return View();
            return new ActionAsPdf("vistaBlancaCotizacionConvenio", new { id = id}) { FileName = "Cotización.pdf" };
        }

        public virtual ViewResult vistaBlancaCotizacionConvenio(int id)
        {
            ViewData["TiposEquipo"] = db.TIPO_EQUIPO.ToList();
            //ViewBag.TiposEquipo = 
            COTIZACION_CONVENIO cotizacion_convenio = db.COTIZACION_CONVENIO.Find(id);
            return View(cotizacion_convenio);
        }


        public virtual ActionResult Create()
        {
            return View(new CotizacionViewModel
                {
                    FECHA_COTIZACION = DateTime.Today,
                    TOTAL_COTIZACION = 0
                });
        }

        [HttpPost]
        public virtual ActionResult Create(CotizacionViewModel cotizacionVM)
        {
            if (ModelState.IsValid)
            {
                COTIZACION_CONVENIO cotizacion = new COTIZACION_CONVENIO
                {
                    RUT_CLIENTE_COTIZACION = cotizacionVM.RUT_CLIENTE,
                    FECHA_COTIZACION = cotizacionVM.FECHA_COTIZACION,
                    TOTAL_COTIZACION = cotizacionVM.TOTAL_COTIZACION,
                    ALCANCES = cotizacionVM.Alcances,
                    VISIBLE = true
                };

                db.COTIZACION_CONVENIO.Add(cotizacion);
                db.SaveChanges();

                return RedirectToAction(Actions.Details(cotizacion.NUMERO_COTIZACION));  
            }
            else
            {
                return View(cotizacionVM);
            }
        }

        public virtual ActionResult Edit(int id)
        {
            COTIZACION_CONVENIO cotizacion_convenio = db.COTIZACION_CONVENIO.Find(id);
            //ViewBag.RUT_CLIENTE = new SelectList(db.CLIENTE, "RUT_CLIENTE", "REGION", cotizacion_convenio.RUT_CLIENTE);
            return View(cotizacion_convenio);
        }

        [HttpPost]
        public virtual ActionResult Edit(COTIZACION_CONVENIO cotizacion_convenio)
        {
            if (ModelState.IsValid)
            {
                db.Entry(cotizacion_convenio).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            //ViewBag.RUT_CLIENTE = new SelectList(db.CLIENTE, "RUT_CLIENTE", "REGION", cotizacion_convenio.RUT_CLIENTE);
            return View(cotizacion_convenio);
        }

        public virtual ActionResult Delete(int id)
        {
            COTIZACION_CONVENIO cotizacion_convenio = db.COTIZACION_CONVENIO.Find(id);
            return View(cotizacion_convenio);
        }

        [HttpPost, ActionName("Delete")]
        public virtual ActionResult DeleteConfirmed(int id)
        {            
            COTIZACION_CONVENIO cotizacion_convenio = db.COTIZACION_CONVENIO.Find(id);
            db.COTIZACION_CONVENIO.Remove(cotizacion_convenio);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        [HttpPost]
        public virtual ActionResult EditFormasDePago(FormasDePagoCotizacionViewModel formasDePagoVM)
        {
            try
            {
                COTIZACION_CONVENIO cotizacion = db.COTIZACION_CONVENIO.Find(formasDePagoVM.NUMERO_COTIZACION);

                if (formasDePagoVM.HayCargoFijo)
                {
                    if (cotizacion.FORMA_DE_PAGO_COTIZACION.Any(e => e.PAGO_TIPO_CARGO_FIJO_COTIZACION != null))
                    {
                        PAGO_TIPO_CARGO_FIJO_COTIZACION cargoFijo = cotizacion.FORMA_DE_PAGO_COTIZACION.First(e => e.PAGO_TIPO_CARGO_FIJO_COTIZACION != null).PAGO_TIPO_CARGO_FIJO_COTIZACION;
                        cargoFijo.PRECIO_CARGO_FIJO = formasDePagoVM.PrecioCargoFijo;
                        db.Entry(cargoFijo).State = EntityState.Modified;
                        db.SaveChanges();
                    }
                    else
                    {
                        FORMA_DE_PAGO_COTIZACION cargoFijo = new FORMA_DE_PAGO_COTIZACION();
                        cargoFijo.PAGO_TIPO_CARGO_FIJO_COTIZACION = new PAGO_TIPO_CARGO_FIJO_COTIZACION
                        {
                            PRECIO_CARGO_FIJO = formasDePagoVM.PrecioCargoFijo
                        };
                        cotizacion.FORMA_DE_PAGO_COTIZACION.Add(cargoFijo);
                        db.SaveChanges();
                    }
                }
                else
                {
                    if (cotizacion.FORMA_DE_PAGO_COTIZACION.Any(e => e.PAGO_TIPO_CARGO_FIJO_COTIZACION != null))
                    {
                        FORMA_DE_PAGO_COTIZACION formaDePago = cotizacion.FORMA_DE_PAGO_COTIZACION.First(e => e.PAGO_TIPO_CARGO_FIJO_COTIZACION != null);
                        PAGO_TIPO_CARGO_FIJO_COTIZACION CargoFijo = formaDePago.PAGO_TIPO_CARGO_FIJO_COTIZACION;

                        db.PAGO_TIPO_CARGO_FIJO_COTIZACION.Remove(CargoFijo);
                        db.SaveChanges();

                        db.FORMA_DE_PAGO_COTIZACION.Remove(formaDePago);
                        db.SaveChanges();
                    }
                }

                if (formasDePagoVM.HayMinimoGarantizadoBlancoYNegro)
                {
                    if (cotizacion.FORMA_DE_PAGO_COTIZACION.Any(e => e.COTIZACION_MING_BN != null))
                    {
                        COTIZACION_MING_BN MinBN = cotizacion.FORMA_DE_PAGO_COTIZACION.First(e => e.COTIZACION_MING_BN != null).COTIZACION_MING_BN;
                        MinBN.MING = formasDePagoVM.PrecioMinGBlancoyNegro;
                        MinBN.PRECIO_HOJA = formasDePagoVM.PrecioHojaBlancoynegro;
                        db.Entry(MinBN).State = EntityState.Modified;
                        db.SaveChanges();
                    }
                    else
                    {
                        FORMA_DE_PAGO_COTIZACION MinBN = new FORMA_DE_PAGO_COTIZACION();
                        MinBN.COTIZACION_MING_BN = new COTIZACION_MING_BN
                        {
                            MING = formasDePagoVM.PrecioMinGBlancoyNegro,
                            PRECIO_HOJA = formasDePagoVM.PrecioHojaBlancoynegro
                        };
                        cotizacion.FORMA_DE_PAGO_COTIZACION.Add(MinBN);
                        db.SaveChanges();
                    }
                }
                else
                {
                    if (cotizacion.FORMA_DE_PAGO_COTIZACION.Any(e => e.COTIZACION_MING_BN != null))
                    {
                        FORMA_DE_PAGO_COTIZACION formaDePago = cotizacion.FORMA_DE_PAGO_COTIZACION.First(e => e.COTIZACION_MING_BN != null);
                        COTIZACION_MING_BN MinBN = formaDePago.COTIZACION_MING_BN;

                        db.COTIZACION_MING_BN.Remove(MinBN);
                        db.SaveChanges();

                        db.FORMA_DE_PAGO_COTIZACION.Remove(formaDePago);
                        db.SaveChanges();

                        //equipo.FORMA__DE_PAGO.Remove(equipo.FORMA__DE_PAGO.First(e => e.MING_B_N != null));
                        //db.SaveChanges();
                    }
                }

                if (formasDePagoVM.HayMinimoGarantizadoColor)
                {
                    if (cotizacion.FORMA_DE_PAGO_COTIZACION.Any(e => e.COTIZACION_MINGCOLOR != null))
                    {
                        COTIZACION_MINGCOLOR MinGC = cotizacion.FORMA_DE_PAGO_COTIZACION.First(e => e.COTIZACION_MINGCOLOR != null).COTIZACION_MINGCOLOR;
                        MinGC.MING = formasDePagoVM.PrecioMinGColor;
                        MinGC.PRECIO_HOJA = formasDePagoVM.PrecioHojaColor;
                        db.Entry(MinGC).State = EntityState.Modified;
                        db.SaveChanges();
                    }
                    else
                    {
                        FORMA_DE_PAGO_COTIZACION MinGC = new FORMA_DE_PAGO_COTIZACION();
                        MinGC.COTIZACION_MINGCOLOR = new COTIZACION_MINGCOLOR
                        {
                            MING = formasDePagoVM.PrecioMinGColor,
                            PRECIO_HOJA = formasDePagoVM.PrecioHojaColor
                        };
                        cotizacion.FORMA_DE_PAGO_COTIZACION.Add(MinGC);
                        db.SaveChanges();
                    }
                }
                else
                {
                    if (cotizacion.FORMA_DE_PAGO_COTIZACION.Any(e => e.COTIZACION_MINGCOLOR != null))
                    {
                        FORMA_DE_PAGO_COTIZACION formaDePAgo = cotizacion.FORMA_DE_PAGO_COTIZACION.First(e => e.COTIZACION_MINGCOLOR != null);
                        COTIZACION_MINGCOLOR MinG = formaDePAgo.COTIZACION_MINGCOLOR;

                        db.COTIZACION_MINGCOLOR.Remove(MinG);
                        db.SaveChanges();

                        db.FORMA_DE_PAGO_COTIZACION.Remove(formaDePAgo);
                        db.SaveChanges();
                    }
                }

                this.ShowMessage(MessageType.Success, "Se guardaron los cambios correctamente.");
                return RedirectToAction(Actions.Details(formasDePagoVM.NUMERO_COTIZACION));
            }
            catch
            {
                this.ShowMessage(MessageType.Error, "No se pudo guardar los cambios de las formas de pago.");
                return RedirectToAction(Actions.Details(formasDePagoVM.NUMERO_COTIZACION));
            }
        }

        #region "Grid Detalles Cotizacion Convenio"

        [HttpPost]
        public virtual ActionResult GridAddDetalleCotizacionConvenio(int NUMERO_COTIZACION)
        {
            EQUIPOS_COTIZACION_CONVENIO detalleCotizacion = new EQUIPOS_COTIZACION_CONVENIO();

            //TIPO_EQUIPO

            if (TryUpdateModel(detalleCotizacion))
            {
                COTIZACION_CONVENIO cotizacion = db.COTIZACION_CONVENIO.Find(NUMERO_COTIZACION);

                cotizacion.EQUIPOS_COTIZACION_CONVENIO.Add(detalleCotizacion);
                db.SaveChanges();

                this.ShowMessage(MessageType.Success, "Se agregó el detalle de cotización.");
                return RedirectToAction(Actions.Details(NUMERO_COTIZACION));
            }
            else
            {
                this.ShowMessage(MessageType.Error, "No se pudo agregar el detalle de cotización.");
                return View();
            }
        }

        [HttpPost]
        public virtual ActionResult GridEditDetalleCotizacionConvenio(int NUMERO_COTIZACION)
        {
            EQUIPOS_COTIZACION_CONVENIO detalleCotizacionVM = new EQUIPOS_COTIZACION_CONVENIO();

            if (TryUpdateModel(detalleCotizacionVM))
            {
                COTIZACION_CONVENIO cotizacion = db.COTIZACION_CONVENIO.Find(NUMERO_COTIZACION);
                EQUIPOS_COTIZACION_CONVENIO detalleCotizacion = cotizacion.EQUIPOS_COTIZACION_CONVENIO.First(d => d.DETALLE_CONVENIO3 == detalleCotizacionVM.DETALLE_CONVENIO3);
                detalleCotizacion.TIPO_EQUIPO = detalleCotizacionVM.TIPO_EQUIPO;

                db.Entry(detalleCotizacion).State = EntityState.Modified;
                db.SaveChanges();

                return RedirectToAction(Actions.Details(NUMERO_COTIZACION));
            }
            else
            {
                this.ShowMessage(MessageType.Error, "No se pudo editar el detalle de cotización.");
                return View();
            }
        }

        [HttpPost]
        public virtual ActionResult GridDeleteDetalleCotizacionConvenio(int NUMERO_COTIZACION)
        {
            EQUIPOS_COTIZACION_CONVENIO detalleCotizacion = new EQUIPOS_COTIZACION_CONVENIO();

            if (TryUpdateModel(detalleCotizacion))
            {
                COTIZACION_CONVENIO cotizacion = db.COTIZACION_CONVENIO.Find(NUMERO_COTIZACION);
                cotizacion.EQUIPOS_COTIZACION_CONVENIO.Remove(db.EQUIPOS_COTIZACION_CONVENIO.Find(detalleCotizacion.NUMERO_COTIZACION, detalleCotizacion.DETALLE_CONVENIO3));
                db.SaveChanges();

                return RedirectToAction(Actions.Details(NUMERO_COTIZACION));
            }
            else
            {
                this.ShowMessage(MessageType.Error, "No se pudo eliminar el detalle de cotización.");
                return View();
            }
        }

        #endregion

        #endregion

        #region "CRUD Cotizaciones de venta directa"

        public virtual ActionResult DetailsVD(int id)
        {
            return View(db.COTIZACION_VENTA_DIRECTA.Find(id));
        }

        public virtual ActionResult CreateVD()
        {
            return View(new CotizacionViewModel
                {
                    FECHA_COTIZACION = DateTime.Today,
                    TOTAL_COTIZACION = 0
                });
        }



        public virtual ActionResult vistaBlancaCotizacionVD(int id)
        {
            COTIZACION_VENTA_DIRECTA cotizacion = db.COTIZACION_VENTA_DIRECTA.Find(id);
            return View(cotizacion);
        }


        [HttpPost]
        public virtual ActionResult CreateVD(CotizacionViewModel cotizacionVM)
        {
            if (ModelState.IsValid)
            {
                COTIZACION_VENTA_DIRECTA cotizacion = new COTIZACION_VENTA_DIRECTA
                {
                    RUT_CLIENTE_COTIZACION = cotizacionVM.RUT_CLIENTE,
                    FECHA_INSTALACION = cotizacionVM.FECHA_COTIZACION,
                    TOTAL = cotizacionVM.TOTAL_COTIZACION,
                    VISIBLE = true
                };

                db.COTIZACION_VENTA_DIRECTA.Add(cotizacion);
                db.SaveChanges();
                return RedirectToAction(Actions.DetailsVD(cotizacion.ID_COTIZACION_VENTA_DIRECATA));
            }
            else
            {
                return View();
            }
        }

        public virtual ActionResult EditVD(int id)
        {
            COTIZACION_VENTA_DIRECTA cotizacion = db.COTIZACION_VENTA_DIRECTA.Find(id);
            return View(new EditCotizacionVentaDirectaViewModel
                {
                    NUMERO_COTIZACION = cotizacion.ID_COTIZACION_VENTA_DIRECATA,
                    RUT_CLIENTE = cotizacion.RUT_CLIENTE_COTIZACION,
                    FECHA_COTIZACION = cotizacion.FECHA_INSTALACION ?? DateTime.MinValue,
                    TOTAL_COTIZACION = cotizacion.TOTAL
                });
        }

        [HttpPost]
        public virtual ActionResult EditVD(EditCotizacionVentaDirectaViewModel cotizacionVM)
        {
            COTIZACION_VENTA_DIRECTA cotizacion = db.COTIZACION_VENTA_DIRECTA.Find(cotizacionVM.NUMERO_COTIZACION);
            cotizacion.RUT_CLIENTE_COTIZACION = cotizacionVM.RUT_CLIENTE;
            cotizacion.FECHA_INSTALACION = cotizacionVM.FECHA_COTIZACION;
            cotizacion.TOTAL = cotizacionVM.TOTAL_COTIZACION;

            db.Entry(cotizacion).State = EntityState.Modified;
            db.SaveChanges();

            return RedirectToAction(Actions.DetailsVD(cotizacion.ID_COTIZACION_VENTA_DIRECATA));
        }

        public virtual ActionResult DeleteVD(int id)
        {
            return View(db.COTIZACION_VENTA_DIRECTA.Find(id));
        }

        [HttpPost, ActionName("DeleteVD")]
        public virtual ActionResult DeleteVDConfirmed(int id)
        {
            COTIZACION_VENTA_DIRECTA cotizacion = db.COTIZACION_VENTA_DIRECTA.Find(id);

            db.COTIZACION_VENTA_DIRECTA.Remove(cotizacion);
            db.SaveChanges();

            return RedirectToAction(Actions.Index());
        }

        #region "Grid Detalles Cotizacion Venta Directa"

        [HttpPost]
        public virtual ActionResult GridAddDetalleCotizacionVentaDirecta()
        {
            return View();
        }

        [HttpPost]
        public virtual ActionResult GridEditDetalleCotizacionVentaDirecta()
        {
            return View();
        }

        [HttpPost]
        public virtual ActionResult GridDeleteDetalleCotizacionVentaDirecta()
        {
            return View();
        }

        #endregion

        #endregion

        #region Validaciones

        public virtual JsonResult VerificarRut(string RUT_CLIENTE)
        {
            //return Json(RUT_CLIENTE != null ? db.CLIENTE.Any(c => c.RUT_CLIENTE.Equals(RUT_CLIENTE)) : true, JsonRequestBehavior.AllowGet);
            return Json(db.CLIENTE.Any(c => c.RUT_CLIENTE.Equals(RUT_CLIENTE)), JsonRequestBehavior.AllowGet);
        }

        [OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
        public virtual JsonResult ValidaBusquedaVacia(string Criterios, string AreaBusqueda)
        {
            switch (Criterios)
            {
                case "ID":
                    int codigo;
                    return Int32.TryParse(AreaBusqueda, out codigo)
                        ? db.COTIZACION_CONVENIO.Any(c => c.NUMERO_COTIZACION == codigo)
                            ? Json(true, JsonRequestBehavior.AllowGet)
                            : Json("No se encontraron clientes con el rut ingresado", JsonRequestBehavior.AllowGet)
                        : Json("El código ingresado no es correcto (no puede contener letras, sólo números)", JsonRequestBehavior.AllowGet);
                //case "Rut":
                //    return db.COTIZACION_CONVENIO.Any(c => c.RUT_CLIENTE.Equals(AreaBusqueda))
                //        ? Json(true, JsonRequestBehavior.AllowGet)
                //        : Json("No se encontraron cotizaciones de clientes con el rut ingreasado", JsonRequestBehavior.AllowGet);
                //case "Nombre":
                //    return db.COTIZACION_CONVENIO.Any(c => c.CLIENTE.NOMBRE.Contains(AreaBusqueda))
                //        ? Json(true, JsonRequestBehavior.AllowGet)
                //        : Json("No se encontraron clientes que tengan \"" + AreaBusqueda + "\"", JsonRequestBehavior.AllowGet);
                default:
                    return Json("Criterio de búsqueda desconocido", JsonRequestBehavior.AllowGet);
            }
        }

        #endregion

        #region Busqueda

        [ChildActionOnly]
        public virtual ActionResult Search()
        {
            return PartialView();
        }

        public virtual ActionResult Busqueda()
        {
            return View();
        }

        public virtual ActionResult ResultadoBusqueda(string Criterios, string AreaBusqueda)
        {
            switch (Criterios)
            {
                case "ID":
                    int codigo;
                    return View(new ResultadoBusquedaCotizacionViewModel
                    {
                        Resultado = Int32.TryParse(AreaBusqueda, out codigo)
                                    ? db.COTIZACION_CONVENIO.Where(c => c.NUMERO_COTIZACION == codigo).ToList()
                                    : new List<COTIZACION_CONVENIO>(),
                        CriterioParaOrdenar = Criterios
                    });
                //case "Rut":
                //    return View(new ResultadoBusquedaCotizacionViewModel
                //    {
                //        Resultado = db.COTIZACION_CONVENIO.Where(c => c.RUT_CLIENTE.Equals(AreaBusqueda)).ToList(),
                //        CriterioParaOrdenar = Criterios
                //    });
                //case "Nombre":
                //    return View(new ResultadoBusquedaCotizacionViewModel
                //    {
                //        Resultado = db.COTIZACION_CONVENIO.Where(c => c.CLIENTE.NOMBRE.Contains(AreaBusqueda)).ToList(),
                //        CriterioParaOrdenar = Criterios
                //    });
                default:
                    return PartialView(Views.Search);
            }
        }

        #endregion

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}